Starting in STA mode

Latest update: June 2015

This tutorial demonstrates how to start a FlashAir's wireless LAN in STA mode using iSDIO commands.

Overview

To start in STA mode, use the Connect command regulated by iSDIO.

It's similar to Establish command, and the FlashAir's wireless LAN still needs to be disconnected for it to run properly.

You also need the SSID and Network Key (password) of the network you are going to connect to. In this tutorial, we'll run the Scan command to discover nearby wireless networks.

We're going to be adding to and modifying the source code from Tutorial 4: Starting in AP mode.

Issuing a Connect command

The Connect command will start up the FlashAir's wireless LAN in STA mode. In the background, the FlashAir will also start up HTTP and DHCP servers.

For more information, please read SD Specifications Part E7 Wireless LAN Simplified Addendum Version 1.10 4.2.2 Connect(ssid, networkKey).

To assemble the command data, the following information is required:

  • Command ID ( 2)
  • Sequential ID
  • The number of parameters ( 2)
  • Parameters
    • SSID
    • Network key (password)
    • Security mode

arduino_tutorial_5.ino (partially extracted)

boolean iSDIO_connect(uint32_t sequenceId, const char* ssid, const char* networkKey) {
  Serial.print(F("\nConnect command: \n"));
  memset(buffer, 0, 512);
  uint8_t* p = buffer;
  p = put_command_header(p, 1, 0);
  p = put_command_info_header(p, 0x02, sequenceId, 2);
  p = put_str_arg(p, ssid);
  p = put_str_arg(p, networkKey);
  put_command_header(buffer, 1, (p - buffer));
  printHex(buffer, (p - buffer));
  return card.writeExtDataPort(1, 1, 0x000, buffer) ? true : false;
}

Issuing a Scan command

The Scan command will scan for nearby wireless LAN APs. It will fail if the FlashAir's wireless network is already running.

For more information, please read SD Specifications Part E7 Wireless LAN Simplified Addendum Version 1.10 4.2.1 Scan().

To assemble the command data, the following information is required:

  • Command ID ( 1)
  • Sequential ID
  • The number of parameters ( 0)
    • No parameters

arduino_tutorial_5.ino (partially extracted)

boolean iSDIO_scan(uint32_t sequenceId) {
  Serial.print(F("\nScan: \n"));
  memset(buffer, 0, 512);
  uint8_t* p = buffer;
  p = put_command_header(p, 1, 0);
  p = put_command_info_header(p, 0x01, sequenceId, 0);
  put_command_header(buffer, 1, (p - buffer));
  printHex(buffer, (p - buffer));
  return card.writeExtDataPort(1, 1, 0x000, buffer) ? true : false;
}

Scan results will be available in the Status Register after the command has finished executing. The results are stored in the following format.

Wireless LAN SSID List (SD Specifications Part E7 Wireless LAN Simplified Addendum Version 1.10)

Wireless LAN SSID List

Let's make a function that reads the status register and displays its content.

arduino_tutorial_5.ino (partially extracted)

boolean iSDIO_showScanResult() {
  // Try to output some wifi info.
  if (!card.readExtDataPort(1, 1, 0x200, buffer)) {
    return false;
  }

  uint8_t num = get_u8(buffer + 24);
  Serial.print(F("Number of APs: "));
  Serial.println(num);

  uint8_t* p = buffer + 28;
  for (int i = 0; i < num; i++){
    Serial.print(F(" "));
    Serial.print((const char*)p);
    Serial.print(F(", "));
    printBytes(p + 32, 6);
    Serial.print(F(", "));
    Serial.print(get_u8(p + 38), DEC);
    Serial.print(F(", "));
    switch (get_u8(p + 39)){
      case 0 : Serial.print(F("NoSec")); break;
      case 1 : Serial.print(F("WEP")); break;
      case 2 : Serial.print(F("WPA")); break;
      case 3 : Serial.print(F("WPA2")); break;
      default : Serial.print(F("error")); break;
    }
    Serial.println();
    p += 44;
  }

  return true;
}

Main program

Add the Connect and Scan commands to the main program.

arduino_tutorial_05.ino (partially extracted)

void loop() {
  char ssid[16];
  char networkKey[16];

  if (!iSDIO_status()) {
    Serial.println(F("\nFailed to read status."));
  }

  Serial.print(F("\n0. Show status"));
  Serial.print(F("\n1. Disconnect"));
  Serial.print(F("\n2. Establish"));
  Serial.print(F("\n3. Connect"));
  Serial.print(F("\n4. Scan"));
  Serial.print(F("\n\nCommand? (next sequence id = "));
  Serial.print(nextSequenceId, DEC);
  Serial.println(F(")"));

  while (Serial.available() == 0);
  char command = Serial.read();

  switch (command - '0') {
    .. (snip) ..
    case 3 :
      Serial.print(F("SSID? "));
      inputText(ssid, sizeof(ssid));
      Serial.print(F("Network Key? "));
      inputText(networkKey, sizeof(networkKey));
      if (iSDIO_connect(nextSequenceId, ssid, networkKey) &&
          iSDIO_waitResponse(nextSequenceId)) {
        Serial.println(F("\nSuccess."));
      } else {
        Serial.print(F("\nFailed or waiting. errorCode="));
        Serial.println(card.errorCode(), HEX);
      }
      nextSequenceId++;
      break;
    case 4 :
      if (iSDIO_scan(nextSequenceId) &&
          iSDIO_waitResponse(nextSequenceId) &&
          iSDIO_showScanResult()) {
        Serial.println(F("\nSuccess."));
      } else {
        Serial.print(F("\nFailed or waiting. errorCode="));
        Serial.println(card.errorCode(), HEX);
      }
      nextSequenceId++;
    default :
      Serial.println(F("\nUnknown command."));
      break;
  }
  • Lines 24-27
    Asks the user to input the SSID and network key.

Next, we'll make an inputText() routine that will be used by the code above. It will read input until the user enters ;.

arduino_tutorial_05.ino (partially extracted)

char* inputText(char* buf, uint8_t len) {
  // Read characters until user inputs enter or the buffer gets full.
  uint8_t i = 0;
  while (i < len - 1) {
    while (Serial.available() == 0);
    char c = Serial.read();
    if (c == ';') break;
    buf[i] = c;
    i++;
  }
  buf[i] = 0;
  Serial.println(buf);
  return buf;
}

Execution result

Let's execute the program!

... (snip) ...
0. Show status
1. Disconnect
2. Establish
3. Connect
4. Scan

Command? (next sequence id = 1)

Run Scan.

Input 4 in a box on the top of the serial terminal, and press the Enter key.

Scan: 

00: 01010000180000000000000000000100
01: 0700000000000000

Waiting response 
  Command Processing...
  Process Succeeded
Number of APs: 5
 mynetwork, B86B23663750, 70, WPA2
 flashair_led, B86B23583750, 64, NoSec
 flashair203r, B86B23005049, 61, WPA2
 HWD14_VEGETA, C40528C98B0C, 52, WPA2
 FlashairT5-v2, E8E0B744A7FB, 49, WPA2

Success.

SSID, BSSID (MAC address), signal strength (0-100), and the security mode of nearby wireless networks will be shown on the terminal.

Next, run the Connect command.

Input 3 in a box on the top of the serial terminal, and press the Enter key. A prompt will appear.

SSID?

Type the SSID of the network you want to connect to. You will need to add ; as a delimiter at the end of the SSID. For example, if an SSID is mynetwork, type

mynetwork;

and then press Enter in the input box of the serial terminal. Next, enter a Network key at the next prompt.

Network Key?

will be shown on the screen.

If the connection attempt was successful, you will see a message like the following:

Connect command: 

00: 01010000340000000000000000000200
01: 0B00000002000000090000006D796E65
02: 74776F726B0000000800000031323334
03: 35363738

Waiting response 
  Command Processing...........
  Process Succeeded

Success.

Read iSDIO Status Register
... (snip) ...
 [0440h] Command Response Status #1: id = 2, sequence id = 3, status = Process Succeeded
... (snip) ...
 [0506h] WLAN: No Scan, No WPS, Group Client, STA, Infrastructure, Connected, 
 [0508h] SSID: mynetwork
 [0528h] Encryption Mode: WPA2-PSK and AES
 [0529h] Signal Strength: 98
 [052Ah] Channel: 1
 [0530h] MAC Address: E8E0B758A7FB
 [0540h] ID: 
 [0550h] IP Address: 192.168.43.213
 [0554h] Subnet Mask: 255.255.255.0
 [0558h] Default Gateway: 192.168.43.1
 [055Ch] Preferred DNS Server: 192.168.43.1
 [0560h] Alternate DNS Server: 0.0.0.0
... (snip) ...
Command? (next sequence id = 11)

Sample code

arduino_tutorial_05.zip (24KB)

All sample code on this page is licensed under BSD 2-Clause License.